﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using GamedataLibrary;
using MessageLibrary.Messages;
using MessageLibrary;
using GamedataLibrary.Characters;
using GamedataLibrary.Jutsus;

namespace NarutoClient.Pages
{
    /// <summary>
    /// Interaction logic for BattlePage.xaml
    /// </summary>
    public partial class BattlePage : UserControl
    {
        #region Fields

        MainWindow mainWindow;

        Character myCharacter;
        Character enemyCharacter;

        int[] jutsusCooldowns;

        #endregion // Fields

        #region Constructors

        public BattlePage()
        {
            InitializeComponent();
        }

        public BattlePage(MainWindow window)
        {
            InitializeComponent();

            this.mainWindow = window;

            myCharacter = mainWindow.MyCharacter;

            jutsusCooldowns = new int[4];

            InitializeBattle();
        }

        #endregion // Constructors

        private void confirmButton_Click(object sender, RoutedEventArgs e)
        {
            if (actionListBox.SelectedIndex == -1)
                MessageBox.Show("You have to choose an action.");
            else
            { 
                // odesle akci
                int type = (int)MessageType.Action;
                ActionMessage a = new ActionMessage();
                a.Action = actionListBox.SelectedIndex;

                // odznacime vyber listboxu
                actionListBox.SelectedIndex = -1;

                try
                {
                    // znepristupnime vyber akci a button
                    actionListBox.IsEnabled = false;
                    confirmButton.IsEnabled = false;
                    // zviditelnime cekaci text
                    waitingTextBlock.Visibility = System.Windows.Visibility.Visible;

                    // odesleme data na server
                    byte[] buffer = MessageComposer.Serialize(type, a);
                    mainWindow.Socket.Send(buffer);

                    // ceka na vysledek tahu
                    mainWindow.Communication.ReceiveState();

                }
                catch (SocketException ex)
                {
                    MessageBox.Show("CONNECTION ERROR!");
                    mainWindow.Close();
                }

                // zobrazi vysledek tahu 
                //Update();
            }
        }

        /// <summary>
        /// Reakce na event, ktery meni popis techniky, ktera je zrovna vybrana.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void actionListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (actionListBox.SelectedIndex == 0)
            {
                DamageJutsu dmgJutsu = (DamageJutsu)myCharacter.Jutsu1;

                if (jutsusCooldowns[0] == 0)
                {
                    confirmButton.IsEnabled = true;

                    descriptionTextBox.Text = "Damage: " + dmgJutsu.Damage +
                        ", Chance to hit: " + myCharacter.Jutsu1.Chance +
                        "%, Cooldown: " + myCharacter.Jutsu1.Cooldown +
                        ", Usable now\n" + myCharacter.Jutsu1.Description;
                }
                else
                {
                    confirmButton.IsEnabled = false;

                    descriptionTextBox.Text = "Damage: " + dmgJutsu.Damage + 
                        ", Chance to hit: " + myCharacter.Jutsu1.Chance +
                        "%, Cooldown: " + myCharacter.Jutsu1.Cooldown +
                        ", Reusable in " + jutsusCooldowns[0] + " rounds\n" + myCharacter.Jutsu1.Description;
                }
            }
            else if (actionListBox.SelectedIndex == 1)
            {
                DamageJutsu dmgJutsu = (DamageJutsu)myCharacter.Jutsu2;

                if (jutsusCooldowns[1] == 0)
                {
                    confirmButton.IsEnabled = true;

                    descriptionTextBox.Text = "Damage: " + dmgJutsu.Damage + 
                        ", Chance to hit: " + myCharacter.Jutsu2.Chance +
                        "%, Cooldown: " + myCharacter.Jutsu2.Cooldown +
                        ", Usable now\n" + myCharacter.Jutsu2.Description;
                }
                else
                {
                    confirmButton.IsEnabled = false;

                    descriptionTextBox.Text = "Damage: " + dmgJutsu.Damage + 
                        ", Chance to hit: " + myCharacter.Jutsu2.Chance +
                        "%, Cooldown: " + myCharacter.Jutsu2.Cooldown +
                        ", Reusable in " + jutsusCooldowns[1] + " rounds\n" + myCharacter.Jutsu2.Description;
                }
            }
            else if (actionListBox.SelectedIndex == 2)
            {
                StunJustu stun = (StunJustu)myCharacter.Jutsu3;

                if (jutsusCooldowns[2] == 0)
                {
                    confirmButton.IsEnabled = true;

                    descriptionTextBox.Text = "Stun duration: " + stun.Duration + 
                    ", Chance to hit: " + myCharacter.Jutsu3.Chance +
                        "%, Cooldown: " + myCharacter.Jutsu3.Cooldown +
                        ", Usable now\n" + myCharacter.Jutsu3.Description;
                }
                else
                {
                    confirmButton.IsEnabled = false;

                    descriptionTextBox.Text = "Stun duration: " + stun.Duration + 
                        ", Chance to hit: " + myCharacter.Jutsu3.Chance +
                        "%, Cooldown: " + myCharacter.Jutsu3.Cooldown +
                        ", Reusable in " + jutsusCooldowns[2] + " rounds\n" + myCharacter.Jutsu3.Description;
                }
            }
            else if (actionListBox.SelectedIndex == 3)
            {
                DefenseJutsu defense = (DefenseJutsu)myCharacter.Jutsu4;

                if (jutsusCooldowns[3] == 0)
                {
                    confirmButton.IsEnabled = true;

                    descriptionTextBox.Text = "Increases defense by: " + defense.Defense +
                        "%, Chance to hit: " + myCharacter.Jutsu4.Chance +
                        "%, Cooldown: " + myCharacter.Jutsu4.Cooldown +
                        ", Usable now\n" + myCharacter.Jutsu4.Description;
                }
                else
                {
                    confirmButton.IsEnabled = false;

                    descriptionTextBox.Text = "Increases defense by: " + defense.Defense + 
                        "Chance to hit: " + myCharacter.Jutsu4.Chance +
                        "%, Cooldown: " + myCharacter.Jutsu4.Cooldown +
                        ", Reusable in " + jutsusCooldowns[3] + " rounds\n" + myCharacter.Jutsu4.Description;
                }
            }
            else if (actionListBox.SelectedIndex == 4)
            {
                descriptionTextBox.Text = "Wait for the next round.";
                confirmButton.IsEnabled = true;
            }
            else
            {
                descriptionTextBox.Text = string.Empty;
            }
        }

        /// <summary>
        /// Nacte data a zinicializuje data pro boj.
        /// </summary>
        private void InitializeBattle()
        {
            // nastavi moje udaje
            myLogin.Text = mainWindow.Login;
            myCharacterName.Text = mainWindow.MyCharacter.Name;
            myHealth.Text = "1000";
            myImage.Source = new BitmapImage(new Uri(myCharacter.ImageURL));

            // nastavi udaje protivnika
            enemyHealth.Text = "1000";
            //mainWindow.Communication.Receive();
            //mainWindow.Communication.Join();

            if (mainWindow.Communication.Type != (int)MessageType.Action)
            {
                MessageBox.Show("ERROR");
                mainWindow.Close();
            }
            else
            {
                try
                {
                    ActionMessage a = (ActionMessage)mainWindow.Communication.Message;

                    if (a.Action == (int)CharactersID.Naruto)
                        enemyCharacter = new Naruto();
                    else if (a.Action == (int)CharactersID.Sasuke)
                        enemyCharacter = new Sasuke();
                    else if (a.Action == (int)CharactersID.Sakura)
                        enemyCharacter = new Sakura();
                    else if (a.Action == (int)CharactersID.Minato)
                        enemyCharacter = new Minato();
                    else if (a.Action == (int)CharactersID.Hiruzen)
                        enemyCharacter = new Hiruzen();

                    enemyCharacterName.Text = enemyCharacter.Name;
                    enemyImage.Source = new BitmapImage(new Uri(enemyCharacter.ImageURL));
                }
                catch (NullReferenceException ex)
                {
                    MessageBox.Show("ERROR");
                    mainWindow.Close();
                }
            }

            // nacte jutsu z knihovny
            actionListBox.Items.Add(myCharacter.Jutsu1.Name);
            actionListBox.Items.Add(myCharacter.Jutsu2.Name);
            actionListBox.Items.Add(myCharacter.Jutsu3.Name);
            actionListBox.Items.Add(myCharacter.Jutsu4.Name);
            actionListBox.Items.Add("Wait");

            // zpristupni vsechny jutsu
            for (int i = 0; i < jutsusCooldowns.Length; i++)
            {
                jutsusCooldowns[i] = 0;
            }
        }

        /// <summary>
        /// Updatuje stav boje po jednotlivych tazich.
        /// </summary>
        public void Update()
        {
            int type = mainWindow.Communication.Type;
            StateMessage msg = null;

            // kontrola spravnosti prijate zpravy
            if (type != (int)MessageType.State)
                MessageBox.Show("ERROR");
            else
            {
                msg = (StateMessage)mainWindow.Communication.Message;
            }

            /// updatujeme log
            logTextBox.Text = msg.MyLog  + "\n" + logTextBox.Text;

            /// kontrola cooldownu
            jutsusCooldowns[0] = msg.Jutsu1Cooldown;
            jutsusCooldowns[1] = msg.Jutsu2Cooldown;
            jutsusCooldowns[2] = msg.Jutsu3Cooldown;
            jutsusCooldowns[3] = msg.Jutsu4Cooldown;
            
            /// zobrazime cooldowny
            if (msg.Jutsu1Cooldown > 0)
                jutsu1Cooldown.Text = msg.Jutsu1Cooldown.ToString();
            else
                jutsu1Cooldown.Text = string.Empty;

            if (msg.Jutsu2Cooldown > 0)
                jutsu2Cooldown.Text = msg.Jutsu2Cooldown.ToString();
            else
                jutsu2Cooldown.Text = string.Empty;

            if (msg.Jutsu3Cooldown > 0)
                jutsu3Cooldown.Text = msg.Jutsu3Cooldown.ToString();
            else
                jutsu3Cooldown.Text = string.Empty;

            if (msg.Jutsu4Cooldown > 0)
                jutsu4Cooldown.Text = msg.Jutsu4Cooldown.ToString();
            else
                jutsu4Cooldown.Text = string.Empty;

            /// zobrazime STUNNED, pokud je postava stunnuta
            if (msg.MeStunned > 0) meStunned.Visibility = System.Windows.Visibility.Visible;
            else meStunned.Visibility = System.Windows.Visibility.Hidden;

            if (msg.EnemyStunned > 0) enemyStunned.Visibility = System.Windows.Visibility.Visible;
            else enemyStunned.Visibility = System.Windows.Visibility.Hidden;

            /// kontrola, jestli skoncil boj
            // jestli jsou oba hraci zivy
            if (msg.MyHealth > 0 && msg.EnemyHealth > 0)
            {
                myHealth.Text = msg.MyHealth.ToString();
                enemyHealth.Text = msg.EnemyHealth.ToString();
            }
            // nebo je jeden z nich mrtvy
            else
            {
                if (msg.MyHealth <= 0)
                    myHealth.Text = "0";
                else
                    myHealth.Text = msg.MyHealth.ToString();

                if (msg.EnemyHealth <= 0)
                    enemyHealth.Text = "0";
                else
                    enemyHealth.Text = msg.EnemyHealth.ToString();

                if (msg.MyHealth > 0 && msg.EnemyHealth <= 0)
                    mainWindow.Content = new ResultPage(mainWindow, "You WIN!");
                else if (msg.MyHealth <= 0 && msg.EnemyHealth > 0)
                    mainWindow.Content = new ResultPage(mainWindow, "You LOSE!");
                else if (msg.MyHealth < 0 && msg.EnemyHealth < 0)
                    mainWindow.Content = new ResultPage(mainWindow, "DRAW!");
                else
                    mainWindow.Content = new ResultPage(mainWindow, "ERROR!");
            }

            /// kontrola, jestli jsem zastunovany
            if (msg.MeStunned > 0)
            {
                for (int i = 0; i < jutsusCooldowns.Length; i++)
                {
                    jutsusCooldowns[i] = msg.MeStunned;
                }
            }

        }

    }
}
